package com.kaguya.builder;

/**
 *
 * 建造者模式 创建型2 --简化
 * 在平常遇到有许多属性的复杂实体类时，赋值十分的繁琐，
 * 当一个类的构造函数参数个数超过4个，而且这些参数有些是可选的参数，考虑使用构造者模式。
 */
public class BuilderTest2 {
    public static void main(String[] args) {
        //使用实体类的静态内部类Builder 创建对象
        Computer computer = new Computer.Builder("i5 9400","ddr4 2666")
                .setUsbCount(3)
                .setKeyboard("斗鱼102")
                .setDisplay("g249g")
                .build();

        System.out.println(computer.toString());
    }
}

/**
 * 实体类
 */
class Computer{

    //复杂属性，有可选的属性，可以考虑使用建造者模式
    private final String cpu;//必须
    private final String ram;//必须
    private final int usbCount;//可选
    private final String keyboard;//可选
    private final String display;//可选

    //全参构造函数，参数为内部类Builder
    private Computer(Builder builder) {
        this.cpu = builder.cpu;
        this.ram = builder.ram;
        this.usbCount = builder.usbCount;
        this.keyboard = builder.keyboard;
        this.display = builder.display;
    }

    /**
     * toString
     * @return String
     */
    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", ram='" + ram + '\'' +
                ", usbCount=" + usbCount +
                ", keyboard='" + keyboard + '\'' +
                ", display='" + display + '\'' +
                '}';
    }

    /**
     * 静态内部类 Builder
     */
    static class Builder{

        //被建造者属性
        private String cpu;//必须
        private String ram;//必须
        private int usbCount;//可选
        private String keyboard;//可选
        private String display;//可选

        //通过build方法返回实例对象
        public Computer build(){
            return new Computer(this);
        }

        //必需的参数
        public Builder(String cpu,String ram){
            this.cpu = cpu;
            this.ram = ram;
        }

        //可选的参数，return自身，可链式调用
        public Builder setUsbCount(int usbCount) {
            this.usbCount = usbCount;
            return this;
        }

        public Builder setKeyboard(String keyboard) {
            this.keyboard = keyboard;
            return this;
        }

        public Builder setDisplay(String display) {
            this.display = display;
            return this;
        }

        //省略getter方法
    }
}